package com.molichuxing.gateway.bff.order.services.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.order.convertor.Convert;
import com.molichuxing.gateway.bff.order.entity.response.*;
import com.molichuxing.gateway.bff.order.services.OrderExclusivelBffService;
import com.molichuxing.services.business.dto.response.OrderExclusivelBizDto;
import com.molichuxing.services.business.service.OrderExclusivelBizService;
import com.molichuxing.services.business.service.OrderTradeFlowBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 专属里程订单相关bff
 * 
 * @author zoumingyu
 * @date 2019年8月23日
 *
 */
@Service("orderExclusivelBffService")
public class OrderExclusivelBffServiceImpl implements OrderExclusivelBffService {
	private static final Logger logger = LoggerFactory.getLogger(OrderExclusivelBffServiceImpl.class);

	@Resource
	private OrderExclusivelService orderExclusivelService;

	@Resource
	private OrderExclusivelBizService orderExclusivelBizService;

	@Resource
	private OrderScheduleService orderScheduleService;

	@Resource
	private OrderTradeFlowBizService orderTradeFlowBizService;

	@Resource
	private OrderReturnService orderReturnService;

	@Resource
	private UserService userService;

	@Resource
	private StoreService storeService;

	@Resource
	private CarService carService;

	@Resource
	private VehicleBizService vehicleBizService;

	@Resource
	private PaymentService paymentService;

	/**
	 * 分页获取专属里程订单信息
	 * 
	 * @param params
	 *            listType：列表类型-enum <br />
	 *            orderStatus：订单状态-enum <br />
	 *            orderCode：订单号-long <br />
	 *            userName：用户账号-string <br />
	 *            userRealName：用户姓名-string <br />
	 *            userPhone：用户手机号-string <br />
	 *            storeId：下单门店id-int <br />
	 *            orderTimeStart：下单开始时间-LocalDate <br />
	 *            orderTimeEnd：下单结束时间-LocalDate <br />
	 * @param dealerId
	 *            经销商id
	 * @param pageNum
	 *            页数
	 * @param pageSize
	 *            每页条数
	 * @return
	 * @throws Exception
	 */
	@Override
	public Paged<OrderExclusivelVo> getOrderList(Map<String, Object> params, Integer dealerId, int pageNum,
			int pageSize) throws Exception {
		Paged<OrderExclusivelVo> result = new Paged<>(new ArrayList<>(), 0, pageSize);
		params.put("source", 2);
		// 根据经销商id查询经销商下门店id
		List<Integer> dealerStoreIds = storeService.getAllStoreIdByDealer(dealerId);
		if (dealerStoreIds == null || dealerStoreIds.isEmpty()) {
			// 经销商下无门店信息，查询tab标签
			result.setTab(orderExclusivelService.getStatusStatistics(
					ObjectCastUtil.castEmun(params.get("listType"), OrderListTypeEnum.class), dealerStoreIds));
			return result;
		}

		// 判断查询条件是否有用户信息
		if (StringUtils.isNotBlank(ObjectCastUtil.castString(params.get("userName")))
				|| StringUtils.isNotBlank(ObjectCastUtil.castString(params.get("userRealName")))
				|| StringUtils.isNotBlank(ObjectCastUtil.castString(params.get("userPhone")))) {
			// 查询用信息
			List<UserDto> userDtoList = userService.getUserList(ObjectCastUtil.castString(params.get("userName")),
					ObjectCastUtil.castString(params.get("userRealName")),
					ObjectCastUtil.castString(params.get("userPhone")));
			if (userDtoList == null || userDtoList.isEmpty()) {
				// 用户不存在,查询tab标签
				result.setTab(orderExclusivelService.getStatusStatistics(
						ObjectCastUtil.castEmun(params.get("listType"), OrderListTypeEnum.class), dealerStoreIds));
				return result;
			}
			List<Integer> userIdList = new ArrayList<>();
			for (UserDto userDto : userDtoList) {
				userIdList.add(userDto.getId());
			}
			params.put("userIds", userIdList);
			params.remove("userName");
			params.remove("userRealName");
			params.remove("userPhone");
			logger.info("[getOrderList]分页获取专属里程订单信息userIds：" + userIdList);
		}

		// 判断查询条件是否有门店信息
		Integer storeId = ObjectCastUtil.castInteger(params.get("storeId"));
		if (storeId != null) {
			// 判断该门店是否属于该经销商
			if (!dealerStoreIds.contains(storeId)) {
				// 不属于该经销商
				result.setTab(orderExclusivelService.getStatusStatistics(
						ObjectCastUtil.castEmun(params.get("listType"), OrderListTypeEnum.class), dealerStoreIds));
				return result;
			}
			params.put("storeIds", Arrays.asList(params.get("storeId")));
			params.remove("storeId");
		} else {
			params.put("storeIds", dealerStoreIds);
		}
		params.put("dealerStoreIds", dealerStoreIds);

		// 车架号、车牌号
		String vin = ObjectCastUtil.castString(params.get("vin"));
		String licencePlate = ObjectCastUtil.castString(params.get("licencePlate"));
		if (vin != null || licencePlate != null) {
			CarDto car = carService.getByVinLicencePlate(vin, licencePlate);
			if (car == null) {
				result.setTab(orderExclusivelService.getStatusStatistics(
						ObjectCastUtil.castEmun(params.get("listType"), OrderListTypeEnum.class), null));
				return result;

			}
			params.put("carId", car.getId());
		}

		Paged<OrderExclusivelBizDto> orderExclusivelBizDtoPage = orderExclusivelBizService.getOrderList(params, pageNum,
				pageSize);
		// 判断是否查询为空
		if (orderExclusivelBizDtoPage == null) {
			// 查询tab标签
			result.setTab(orderExclusivelService.getStatusStatistics(
					ObjectCastUtil.castEmun(params.get("listType"), OrderListTypeEnum.class), dealerStoreIds));
			return result;
		} else if (orderExclusivelBizDtoPage.isEmpty()) {
			return result.setTotal(orderExclusivelBizDtoPage.getTotal()).setTab(orderExclusivelBizDtoPage.getTab());
		}

		result.setTotal(orderExclusivelBizDtoPage.getTotal()).setTab(orderExclusivelBizDtoPage.getTab());
		// 用户id集合
		List<Integer> userIds = new ArrayList<>();
		// 门店id集合
		List<Integer> storeIds = new ArrayList<>();
		// 车型id集合
		List<Integer> vehicleIds = new ArrayList<>();
		// 车辆id集合
		List<Integer> carIds = new ArrayList<>();
		for (OrderExclusivelBizDto orderExclusivelBizDto : orderExclusivelBizDtoPage.getList()) {
			userIds.add(orderExclusivelBizDto.getUserId());
			storeIds.add(orderExclusivelBizDto.getPlaceStoreId());
			vehicleIds.add(orderExclusivelBizDto.getVehicleId());
			carIds.add(orderExclusivelBizDto.getCarId());
			result.getList().add(Convert.toOrderExclusivelVo(orderExclusivelBizDto));
		}
		// 查询用户
		Map<Integer, UserDto> userMap = userService.getUsers(userIds);
		// 查询门店
		Map<Integer, StoreDto> storeMap = storeService.getStoreMapByIds(storeIds);
		// 查询车型
		Map<Integer, String> vehicleMap = vehicleBizService.getVehicleFullName(vehicleIds);
		// 查询车辆
		Map<Integer, CarDto> carMap = null;
		if (!carIds.isEmpty()) {
			carMap = carService.getCarByIds(carIds);
		}
		if ((userMap == null || userMap.isEmpty()) && (storeMap == null || storeMap.isEmpty())
				&& (vehicleMap == null || vehicleMap.isEmpty()) && (carMap == null || carMap.isEmpty())) {
			return result;
		}

		for (OrderExclusivelVo orderExclusivelVo : result.getList()) {
			// 用户
			UserDto userDto = userMap == null ? null
					: userMap.isEmpty() ? null : userMap.get(orderExclusivelVo.getUserId());
			// 用户账号
			orderExclusivelVo.setUserName(userDto == null ? null : userDto.getName());
			// 用户手机号
			orderExclusivelVo.setUserPhone(userDto == null ? null : userDto.getPhone());
			// 用户姓名
			orderExclusivelVo.setUserRealName(userDto == null ? null : userDto.getRealName());
			// 门店
			StoreDto storeDto = storeMap == null ? null
					: storeMap.isEmpty() ? null : storeMap.get(orderExclusivelVo.getPlaceStoreId());
			// 下单门店(简称)
			orderExclusivelVo.setPlaceStoreName(storeDto == null ? null : storeDto.getShortName());
			// 车型名称
			orderExclusivelVo
					.setVehicleName(vehicleMap == null ? null : vehicleMap.get(orderExclusivelVo.getVehicleId()));

			// 车辆信息
			if (carMap == null || carMap.isEmpty()) {
				continue;
			}
			CarDto car = carMap.get(orderExclusivelVo.getCarId());
			// 车架号
			orderExclusivelVo.setVin(car == null ? null : car.getVin());
			// 车牌号
			orderExclusivelVo.setLicencePlate(car == null ? null : car.getLicencePlate());
		}

		return result;
	}

	/**
	 * 获取专属里程订单交易流程
	 * 
	 * @param orderCode
	 *            订单号
	 * @param listType
	 *            列表类型-enum
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<OrderTradeFlowVo> getOrderTradeFlow(Long orderCode, OrderListTypeEnum listType) throws Exception {
		return orderCode == null ? null
				: Convert.toOrderTradeFlowVo(orderTradeFlowBizService.getExclusivelOrderFlow(orderCode, listType));
	}

	/**
	 * 获取专属里程订单基础信息
	 * 
	 * @param orderCode
	 *            订单号
	 * @return
	 * @throws Exception
	 */
	@Override
	public OrderExclusivelBaseVo getOrderBase(Long orderCode) throws Exception {
		OrderExclusivelBaseVo result = null;

		OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(orderCode);
		if (orderExclusivelDto == null) {
			return result;
		}

		result = Convert.toOrderExclusivelBaseVo(orderExclusivelDto);

		// 查询门店信息
		StoreDto storeDto = storeService.getStoreById(orderExclusivelDto.getPlaceStoreId());
		// 查询车型信息
		String vehicleName = vehicleBizService.getVehicleName(orderExclusivelDto.getVehicleId());
		// 查询车辆信息
		CarDto carDto = null;
		if (orderExclusivelDto.getCarId() != null) {
			carDto = carService.getCarById(orderExclusivelDto.getCarId());
		}

		// 门店简称
		result.setPlaceStoreName(storeDto.getShortName());
		// 车型名称
		result.setVehicleName(vehicleName);
		// 车架号
		result.setVin(carDto == null ? null : carDto.getVin());
		// 车牌号
		result.setLicensePlate(carDto == null ? null : carDto.getLicencePlate());

		result.setBusinessType(OrderTypeEnum.EXCLUSIVEL.getValue());
		result.setBusinessTypeStr(OrderTypeEnum.EXCLUSIVEL.getName());

		return result;
	}

	/**
	 * 获取订单费用交易明细
	 * 
	 * @param orderCode
	 *            订单号
	 * @return
	 */
	@Override
	public List<OrderCostDetailsVo> getOrderCostDetails(Long orderCode) {
		List<OrderCostDetailsVo> result = null;
		OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(orderCode);
		if (orderExclusivelDto == null) {
			return result;
		}
		result = new ArrayList<>();
		String payWayStr = null;
		LocalDateTime paySuccessTime = null;
		Integer payStatus = null;
		String payStatusStr = null;
		// 判断该订单是否已支付
		if (!OrderExclusivelStatusEnum.TRADE_UNPAID.equals(orderExclusivelDto.getOrderStatus())
				&& !OrderExclusivelStatusEnum.TRADE_CANCELED.equals(orderExclusivelDto.getOrderStatus())) {
			// 不是待支付和已取消状态，代表已支付，查询支付信息
			List<PaymentDto> paymentDtoList = paymentService.getListByOrderCode(orderCode,
					PaymentStatusEnum.SUCCESS_PAYMENT.getValue(), PaymentCostTypeEnum.SUBSCRIBE.getValue());
			if (paymentDtoList != null && !paymentDtoList.isEmpty()) {
				payWayStr = paymentDtoList.get(0).getPayWay().getName();
				paySuccessTime = paymentDtoList.get(0).getPayTime();
				payStatus = paymentDtoList.get(0).getPayStatus().getValue();
				payStatusStr = paymentDtoList.get(0).getPayStatus().getName();
			}
		}
		// 租车费
		OrderCostDetailsVo rental = new OrderCostDetailsVo();
		rental.setCostItem("租车费");
		rental.setServiceContent("用车时长：" + orderExclusivelDto.getTransportTime() + "个月");
		rental.setAmount(orderExclusivelDto.getCartFee());
		rental.setPayWayStr(payWayStr);
		rental.setPayStatus(payStatus);
		rental.setPayStatusStr(payStatusStr);
		rental.setPaySuccessTime(paySuccessTime);
		result.add(rental);
		// 保证金
		OrderCostDetailsVo deposit = new OrderCostDetailsVo();
		deposit.setCostItem("保证金");
		deposit.setServiceContent("违章违约保证金");
		deposit.setAmount(orderExclusivelDto.getDeposit());
		deposit.setPayWayStr(payWayStr);
		deposit.setPayStatus(payStatus);
		deposit.setPayStatusStr(payStatusStr);
		deposit.setPaySuccessTime(paySuccessTime);
		result.add(deposit);

		return result;
	}

	/**
	 * 获取订单详情还款信息
	 * 
	 * @param orderCode
	 *            订单号
	 * @return
	 */
	@Override
	public OrderExclusivelRepaymentDetailVo getOrderExclusivelRepaymentDetail(Long orderCode) {
		OrderExclusivelRepaymentDetailVo result = null;
		// 查询排期信息
		List<OrderScheduleDto> orderScheduleDtoList = orderScheduleService.getOrderSchedule(orderCode);
		if (orderScheduleDtoList == null || orderScheduleDtoList.isEmpty()) {
			return result;
		}
		// 查询专属里程订单信息
		OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(orderCode);
		if (orderExclusivelDto == null) {
			return result;
		}

		result = new OrderExclusivelRepaymentDetailVo();
		List<OrderRepaymentDetailVo> repaymentDetailList = new ArrayList<>();
		OrderRepaymentDetailVo firstTermsVo = null;
		// 总期数
		Integer totalPeriods = 0;
		// 已还期数
		Integer hasPayPeriods = 0;
		// 总金额
		BigDecimal totalAmount = BigDecimal.ZERO;
		// 已还金额
		BigDecimal hasPayAmount = BigDecimal.ZERO;
		for (OrderScheduleDto orderScheduleDto : orderScheduleDtoList) {
			// 统计数据
			totalPeriods = orderScheduleDto.getTotalPeriods();
			totalAmount = totalAmount.add(orderScheduleDto.getPayable());
			if (OrderScheduleStatusEnum.ALREADY.equals(orderScheduleDto.getStatus())) {
				hasPayPeriods += 1;
				hasPayAmount = hasPayAmount.add(orderScheduleDto.getPayable());
			}
			// 统计首付信息
			if (orderScheduleDto.getPeriods() <= orderExclusivelDto.getFirstTerms()) {
				if (orderScheduleDto.getPeriods() == 1) {
					firstTermsVo = Convert.toOrderRepaymentDetailVo(orderScheduleDto);
					firstTermsVo.setPeriodsStr("首付(" + orderExclusivelDto.getFirstTerms() + "期)");
				} else {
					// 还款金额
					firstTermsVo.setPayable(firstTermsVo.getPayable().add(orderScheduleDto.getPayable()));
				}
				continue;
			}
			OrderRepaymentDetailVo orderRepaymentDetailVo = Convert.toOrderRepaymentDetailVo(orderScheduleDto);
			orderRepaymentDetailVo
					.setPeriodsStr(orderScheduleDto.getPeriods() + "/" + orderScheduleDto.getTotalPeriods());
			repaymentDetailList.add(orderRepaymentDetailVo);
		}
		// 添加首付信息到返回结果
		repaymentDetailList.add(0, firstTermsVo);

		OrderReturnDto orderReturn = null;
		if ((orderExclusivelDto.getOrderStatus().getValue() > OrderExclusivelStatusEnum.RENEGE_ACCEPTED.getValue())) {
			List<OrderRepaymentDetailVo> newRepaymentDetailList = new ArrayList<>();
			orderReturn = orderReturnService.getOrderReturn(orderExclusivelDto.getOrderCode());
			// 判断是否是已还车退租订单
			if (orderReturn == null) {
				// 查询退租时间
				newRepaymentDetailList.add(repaymentDetailList.get(0));
			} else {
				LocalDate returnTime = orderReturn.getReturnTime().toLocalDate();
				repaymentDetailList.forEach(repaymentDetailVo -> {
					if (repaymentDetailVo.getPayableDate().isBefore(returnTime)
							|| repaymentDetailVo.getPayableDate().isEqual(returnTime)) {
						newRepaymentDetailList.add(repaymentDetailVo);
					}
				});
			}

			result.setOrderRepaymentDetail(newRepaymentDetailList);
		} else {
			result.setOrderRepaymentDetail(repaymentDetailList);
		}

		result.setTotalPeriods(totalPeriods);
		result.setHasPayPeriods(hasPayPeriods);
		result.setTotalAmount(totalAmount);
		result.setHasPayAmount(hasPayAmount);

		return result;
	}

}
